package docker

//docker常用命令
//dockerfile 常用命令官方文档：https://docs.docker.com/engine/reference/builder/
//参考资料：https://blog.csdn.net/imouse728/article/details/125654297

/*

//原文：https://blog.csdn.net/imouse728/article/details/125654297
//https://www.bilibili.com/video/BV1ga411H7K3?p=20&vd_source=9f472be914877d0e9104a22c37171c7a

----------Dockerfile制作原则----------
Dockerfile是Docker用来构建镜像的文本文件，包含自定义的指令和格式, 可以通过docker build命令从Dockerfile中构建镜像。

与容器与Dockerfile制作相关的规则如下：

	1.基础镜像尽量首先官镜像中的镜像， FROM指令应该包含参数tag;

	2.编写指令时允分利用一指令生成镜像层的原理，尽量安排相同的，不变的部份放在前面；

	3.ADD和COPY指令很相近，但推荐用COPY, ADD可以下载URL和自动下载文件解压并保留原文件，ADD指令用RUN wget或RUN curl代替；

	4.RUN指令不要在一行中单独使用 RUN apt-get update，应该避免使用它，要用也必须把RUN apt-get update && RUN apt-get install写在同一行；

	5.不要在Dockerfile中做端口映射;

	6.由于容器名称唯一,如果容器要扩容,运行容器时就不能指字容器名称;

	7.一容器一进程;

	8.入口运行程序必须SUSPEND;

	9.对外部依赖的变量不能写死在Dockerfile里,必须通过变量在运行期间注入,如连接库连接配置;

	10.日志目录通过volume挂载

	11.配置参数通过环境变量注入;

	12.带ONBUILD指令的必须带特殊标签；

	13.Dockerfile有任何修改,必须修改tag;




----------dockerfile的指令----------

	FROM   			基础镜像，一切从这里开始构架，centos 设置要制作的镜像基于哪个镜像，FROM指令必须是整个Dockerfile的第一个指令，如果指定的镜像不存在默认会自动从Docker Hub上下载

	MAINTAINER		镜像作者的信息，姓名+邮箱

	RUN				构建镜像时运行的shell命令/exec命令
					语法：
					①RUN command #将会调用/bin/sh -c command
					②RUN [“executable”, “param1”, “param2”] #将会调用exec执行，以避免有些时候shell方式执行时的传递参数问题，而且有些基础镜像可能不包含/bin/sh
					规则：
					多个 RUN 语法，避免多次无用分层，合并层一条，用 && 和 \
						例： RUN apt-get update && apt-get install-y perl \
							pwgen --no-install-recommends && rm -rf \
							/var/lib/apt/lists/*

	ADD				拷贝文件或目录到镜像容器内，如果是URL或压缩包会自动下载或自动解压  步骤：+nginx+mysql+redis等 添加内容
					语法：
						ADD <源文件> <目标目录>
						ADD[“源文件”，”目标目录”]
					注意：
						①如果执行docker build – < somefile即通过标准输入来创建时，ADD指令只支持url方式，另外如果url需要认证，则可以通过RUN wget …或RUN curl …来完成，ADD指令不支持认证。
						② <源文件>路径必须与Dockerfile在同级目录或子目录中，例如不能使用ADD …/somepath，因为在执行docker build时首先做的就是把Dockerfile所在目录包含子目录发送给docker的守护进程。
						③如果 <源文件>是一个url且<目标目录>不是以”/“结尾，则会下载文件并重命名为<目标目录>。
						④如果 <源文件>是一个url且<目标目录>以“/”结尾，则会下载文件到<目标目录>/，url必须是一个正常的路径形式，“http://example.com”像这样的url是不能正常工作的。
						⑤如果 <源文件>是一个本地的压缩包且<目标目录>是以“/”结尾的目录，则会调用“tar -x”命令解压缩，如果<目标目录>有同名文件则覆盖，但 <源文件>是一个url时不会执行解压缩。


	WORKDIR			指定在创建容器后，终端默认登录进来的工作目录，一个落脚点/docker exec -it xx /bin/bash 进来的目录
					WORKDIR指令用于设置Dockerfile中的RUN、CMD和ENTRYPOINT指令执行命令的工作目录(默认为/目录)，该指令在Dockerfile文件中可以出现多次，如果使用相对路径则为相对于WORKDIR上一次的值，例如WORKDIR /data，WORKDIR logs，RUN pwd最终输出的当前目录是/data/logs。
					语法：
						WORKDIR /path/to/workdir

                        WORKDIR/test  #如果没有，会自动创建
						RUN pwd       #输入  /test/dow




	VOLUME			挂载的目录	VOLUME指令用来设置一个挂载点，可以用来让其他容器挂载以实现数据共享或对容器数据的备份、恢复或迁移。
					数据卷是一个特殊的文件或者目录，它将宿主机文件或者目录直接映射进容器中，可供一个或多个容器使用。
					容器数据卷设计的目的就是为了 数据的持久化，它完全独立与容器的生命周期。
					因此，容器删除时，不会删除其挂载的数据卷，也不会存在类似的垃圾机制对容器存在的数据卷进行处理

					Dockerfile中 VOLUME 方式挂载到宿主机上的是匿名卷，在宿主机上是自动匿名挂载到 /var/lib/docker/volumes/ 目录下的

					语法：
						VOLUME [“samepath”]

						as:
						VOLUME ["/logs","/uploadPath"]


	EXPOSE			指定暴露端口配置 -p

	CMD 			指定这个容器启动的时候要运行的命令  只有最有一个会生效，可被替代
					CMD指令中指定的命令会在镜像运行时执行，在Dockerfile中只能存在一个，如果使用了多个CMD指令，则只有最后一个CMD指令有效。当出现ENTRYPOINT指令时，CMD中定义的内容会作为ENTRYPOINT指令的默认参数，也就是说可以使用CMD指令给ENTRYPOINT传递参数。
					语法：
						①CMD [“executable”, “param1”, “param2”] #将会调用exec执行，首选方式
						②CMD [“param1”, “param2”] #当使用ENTRYPOINT指令时，为该指令传递默认参数
						③CMD command [ param1 | param2 ] #将会调用/bin/sh -c执行
					注意：RUN和CMD都是执行命令，他们的差异在于
						RUN中定义的命令会在执行docker build命令创建镜像时执行，
						而CMD中定义的命令会在执行docker run命令运行镜像时执行，
						另外使用第一种语法也就是调用exec执行时，命令必须为绝对路径。


	ENTRYPOINT		指定这个容器启动的时候要运行的命令 可以追加命令
					（1）ENTRYPOINT指令中指定的命令会在镜像运行时执行，在Dockerfile中只能存在一个，如果使用了多个ENTRYPOINT指令，则只有最后一个指令有效。
					（2）ENTRYPOINT指令中指定的命令(exec执行的方式)可以通过docker run来传递参数，例如docker run images -l启动的容器将会把-l参数传递给ENTRYPOINT指令定义的命令并会覆盖CMD指令中定义的默认参数(如果有的话)，但不会覆盖该指令定义的参数，例如ENTRYPOINT [“ls”,“-a”]，CMD [“/etc”],当通过docker run image启动容器时该容器会运行ls -a /etc命令，当使用docker run image -l启动时该容器会运行ls -a -l命令，-l参数会覆盖CMD指令中定义的/etc参数。
					注意：
						①当使用ENTRYPOINT指令时生成的镜像运行时只会执行该指令指定的命令。
						②当出现ENTRYPOINT指令时CMD指令只可能(当ENTRYPOINT指令使用exec方式执行时)被当做ENTRYPOINT指令的参数使用，其他情况则会被忽略。


	COPY 			拷贝文件或目录到镜像容器内，跟ADD类似，但不具备自动下载或解压功能  类型ADD，将我们文件拷贝到镜像中
					语法：
						COPY <源文件> <目标目录>

	ENV             构建的时候设置环境变量/设置容器的环境变量
					注意：
						ENV指令用于设置环境变量，在Dockerfile中这些设置的环境变量也会影响到RUN指令，当运行生成的镜像时这些环境变量依然有效，如果需要在运行时更改这些环境变量可以在运行docker run时添加–env =参数来修改。
						ENV KEY val
						WORKDIR $KEY


	USER            USER指令用于设置用户或uid来运行生成的镜像和执行RUN，如果都不指定，默认是root，一般不指定，CMD和ENTYRYPOINT执行命令。
					语法：
						USER [username|uid]

					as:
						USER [username|uid]

	ONBUILD			当构建一个被继承dockerfile这个时候就会运行ONBUILD的指令触发指令
					ONBUILD指令用来设置一些触发的指令，用于在当该镜像被作为基础镜像来创建其他镜像时（也就是Dockerfile中的FROM为当前镜像时）执行一些操作，ONBUILD中定义的指令会在用于生成其他镜像的Dockerfile文件的FROM指令之后被执行，上述介绍的任何一个指令都可以用于ONBUILD指令，可以用来执行一些因为环境而变化的操作，使镜像更加通用。
					语法：
						ONBUILD [INSTRUCTION]

					注意：
						①ONBUILD中定义的指令在当前镜像的build中不会被执行。
						②可以通过查看docker inspeat image命令执行结果的OnBuild键来查看某个镜像ONBUILD指令定义的内容。
						③ONBUILD中定义的指令会当做引用该镜像的Dockerfile文件的FROM指令的一部分来执行，执行顺序会按ONBUILD定义的先后顺序执行，如果ONBUILD中定义的任何一个指令运行失败，则会使FROM指令中断并导致整个build失败，当所有的ONBUILD中定义的指令成功完成后，会按正常顺序继续执行build。
						④ONBUILD中定义的指令不会继承到当前引用的镜像中，也就是当引用ONBUILD的镜像创建完成后将会清除所有引用的ONBUILD指令。
						⑤ONBUILD指令不允许嵌套，例如ONBUILD ONBUILD ADD . /data是不允许的。
						⑥ONBUILD指令不会执行其定义的FROM或MAINTAINER指令。


	...


----------注意----------

RUN指令exec格式中的参数会当成JSON数据被Docker解析，帮必须使用双引号而不能使用单引号。

RUN指令在构建镜像时执行指令，并生成新的镜像;CMD指令在构建镜像时并不执行任何命令，而是在容器启动时默认将CMD指令作为第一条执行的命令；

ONBUILD指令必须有特殊的标签：
（1）在构建过程中，ONBUILD指令会添加到触发器指令镜像元数据库，这些触发指令不会在当前构建过程中执行;
（2）在构建过程最后，触发器指令会被存储在镜像详情中，其主键是OnBuild,可以使用docker inspect命令查看；
（3）之后该镜像可能作为其他Dockerfile中的FROM指令的参数。在构建过程中，FROM指令会寻找ONBUILD触发器指令，并且会以它们注册的顺序执行。若有触发器指令执行失败，则FROM指令被中止，并返回失败；若所有触发器指令执行成功，则FROM指令完成并继续执行下面的执行。在镜像构建完成之后，触发器指令会被清除，不会被子镜像继承。
（4）使用包含ONBUILD指令的Dockerfile构建的镜像应该有特殊的标签，如easynode:2.0-onbuild.






*/
